package com.sec.android.app.myfiles.module.abstraction;

import android.content.Context;

import com.sec.android.app.myfiles.facade.FacadeItem;
import com.sec.android.app.myfiles.fragment.AbsMyFilesFragment;
import com.sec.android.app.myfiles.fragment.home.HomeFragment;
import com.sec.android.app.myfiles.fragment.home.HomeFragmentItem;
import com.sec.android.app.myfiles.module.ContentObservable;
import com.sec.android.app.myfiles.module.abstraction.FileRecord.StorageType;
import com.sec.android.app.myfiles.navigation.NavigationInfo;
import com.sec.android.app.myfiles.operation.ProgressListener;
import com.sec.android.app.myfiles.provider.DbTableInfo;
import com.sec.android.app.myfiles.util.chain.Chain;
import com.sec.android.app.myfiles.util.chain.ChainBuilder;
import com.sec.android.app.myfiles.widget.listview.AbsListViewImp;

import java.util.ArrayList;

public abstract class AbsModuleLoaderImp implements Chain<AbsModuleLoaderImp> {
    private AbsModuleLoaderImp mNext = null;

    @Override
    public void setNext(AbsModuleLoaderImp next) {
        mNext = next;
    }

    public FileRecord createFileRecord(StorageType storageType, String fullPath) {
        FileRecord ret = null;

        if (getSupportStorage() == storageType) {
            ret = _createFileRecord(fullPath);
        } else {
            if (mNext != null) {
                ret = mNext.createFileRecord(storageType, fullPath);
            }
        }

        return ret;
    }

    public FileRecord createFileRecord(StorageType storageType, int id, String path, String name, long size, long date, int fileType,
                                       int isHidden, int itemCount, int itemCountHidden) {
        FileRecord ret = null;

        if (getSupportStorage() == storageType) {
            ret = _createFileRecord(id, path, name, size, date, fileType, isHidden, itemCount, itemCountHidden);
        } else {
            if (mNext != null) {
                ret = mNext.createFileRecord(storageType, id, path, name, size, date, fileType, isHidden, itemCount, itemCountHidden);
            }
        }

        return ret;
    }

    public AbsFileListAdapterImp createAdapterImp(NavigationInfo navigationInfo, Context context, AbsListViewImp listView) {
        AbsFileListAdapterImp ret = null;
        if (getSupportStorage() == navigationInfo.getStorageType()) {
            ret = _createAdapterImp(context, navigationInfo, listView);
        } else {
            if (mNext != null) {
                ret = mNext.createAdapterImp(navigationInfo, context, listView);
            }
        }

        return ret;
    }

    public AbsProviderImp createProviderImp(Context context, ChainBuilder<AbsProviderImp> builder) {
        if (builder == null) {
            builder = new ChainBuilder<>();
        }

        builder.append(_createProviderImp(context));

        if (mNext != null) {
            mNext.createProviderImp(context, builder);
        }

        return builder.getInstance();
    }

    public DbTableInfo getTableInfo(FileRecord.StorageType storageType) {
        DbTableInfo ret = null;

        if (getSupportStorage() == storageType) {
            ret = _getTableInfoImp();
        } else {
            if (mNext != null) {
                ret = mNext.getTableInfo(storageType);
            }
        }

        return ret;
    }

    public AbsMenuImp createMenuImp(Context context, StorageType storageType) {
        AbsMenuImp ret = null;
        if (getSupportStorage() == storageType) {
            ret = _createMenuImp(context, storageType);
        }

        if (mNext != null) {
            AbsMenuImp nextRet = mNext.createMenuImp(context, storageType);
            if (ret == null) {
                ret = nextRet;
            }
        }
        return ret;
    }

    public AbsFileOperationImp createFileOperationImp(Context context, ProgressListener listener, ChainBuilder<AbsFileOperationImp> builder) {
        if (builder == null) {
            builder = new ChainBuilder<>();
        }

        builder.append(_createFileOperationImp(context, listener));

        if (mNext != null) {
            mNext.createFileOperationImp(context, listener, builder);
        }

        return builder.getInstance();
    }

    public AbsDragAndDrop createDragAndDropImp(AbsMyFilesFragment fragment, StorageType storageType, AbsListViewImp listViewImp) {
        AbsDragAndDrop ret = null;

        if (getSupportStorage() == storageType) {
            ret = _getDragAndDropImp(fragment, listViewImp);
        } else {
            if (mNext != null)
                ret = mNext.createDragAndDropImp(fragment, storageType, listViewImp);
        }

        return ret;
    }

    public void createHomeItem(Context context, HomeFragment fragment, ArrayList<HomeFragmentItem> itemList, boolean isLeftPanel) {
        _createHomeItem(context, fragment, itemList, isLeftPanel);

        if (mNext != null) {
            mNext.createHomeItem(context, fragment, itemList, isLeftPanel);
        }

        return;
    }

    public void addFacadeItemList(ArrayList<FacadeItem> facadeItem) {
        _addFacadeItemList(facadeItem);

        if (mNext != null) {
            mNext.addFacadeItemList(facadeItem);
        }
    }

    public AbsContentObserverImp createContentObserver(Context context, FileRecord record, ContentObservable updater) {
        AbsContentObserverImp ret = null;
        if (record != null) {
            if (getSupportStorage() == record.getStorageType()) {
                ret = _createContentObserver(context, record, updater);
            } else {
                if (mNext != null) {
                    ret = mNext.createContentObserver(context, record, updater);
                }
            }
        }
        return ret;
    }

    public AbsReloadStrategyImp createReloadStrategy(Context context, NavigationInfo navigationInfo) {
        AbsReloadStrategyImp ret = null;
        if (getSupportStorage() == navigationInfo.getStorageType()) {
            ret = _createReloadStrategy(context, navigationInfo);
        } else {
            if (mNext != null) {
                ret = mNext.createReloadStrategy(context, navigationInfo);
            }
        }
        return ret;
    }

    protected abstract FileRecord _createFileRecord(String fullPath);

    protected abstract FileRecord _createFileRecord(int id, String path, String name, long size, long date, int fileType, int isHidden,
                                                    int itemCount, int itemCountHidden);

    protected abstract AbsFileListAdapterImp _createAdapterImp(Context context, NavigationInfo navigationInfo, AbsListViewImp listView);

    protected abstract AbsProviderImp _createProviderImp(Context context);

    protected abstract DbTableInfo _getTableInfoImp();

    protected abstract AbsMenuImp _createMenuImp(Context context, StorageType supportStorage);

    protected abstract AbsFileOperationImp _createFileOperationImp(Context context, ProgressListener listener);

    protected abstract AbsDragAndDrop _getDragAndDropImp(AbsMyFilesFragment fragment, AbsListViewImp listViewImp);

    protected abstract void _createHomeItem(Context context, HomeFragment fragment, ArrayList<HomeFragmentItem> itemList, boolean isLeftPanel);

    protected abstract void _addFacadeItemList(ArrayList<FacadeItem> facadeItem);

    protected abstract StorageType getSupportStorage();

    protected abstract AbsContentObserverImp _createContentObserver(Context context, FileRecord record, ContentObservable updater);

    protected abstract AbsReloadStrategyImp _createReloadStrategy(Context context, NavigationInfo navigationInfo);
}
